#!/usr/bin/python
"""
Usage: git-grep REGEX BASE-DIR DIRS...

Grep for REGEX in BASE-DIR, printing the matches relative to BASE-DIR.
Additionally grep in DIRS, also printing the matches relative to BASE-DIR.

Example for this repo:

etc/git-multi-grep 'ivy.*re' . git/*
"""

#* Imports
import os
import sys
import re
from elisp import *

#* Functions
def git_grep (regex):
    return "git --no-pager grep --full-name -n --no-color -i -I -e " + regex

def git_p (f):
    if file_directory_p (f):
        return file_exists_p (expand_file_name (".git", f))

def print_git (cmd, d = ''):
    try:
        res = shell_command_to_string (cmd)[:-1]
        for match in res.split ("\n"):
            l = len (match)
            if l > 200:
                match = match[:200] + "..."
            print d + match
    except:
        pass

def git_files_in (d):
    r = [expand_file_name (f, d) for f in directory_files (d)]
    return filter (git_p, r)

def expand_globs (dirs_and_globs):
    dirs = []
    for glob in dirs_and_globs:
        m = re.match ("(.*)/\*$", glob)
        if m:
            for x in git_files_in (expand_file_name (m.group (1), base_dir)):
                dirs.append (os.path.relpath (x))
        elif glob == "*":
            for x in git_files_in (base_dir):
                dirs.append (os.path.relpath (x))
        else:
            dirs.append (glob)
    return dirs

#* Assign args
regex = re.sub (r"\\", "\\\\\\\\", sys.argv[1])
base_dir = expand_file_name (sys.argv[2])
dirs_and_globs = sys.argv[3:]

# print ("looking for '%s' in %s" % (regex, base_dir))
# print sys.argv[1:]
# exit (0)

#* Do work
cmd = git_grep (regex)
os.chdir (base_dir)

for d in [""] + expand_globs (dirs_and_globs):
    ed = expand_file_name (d, base_dir)
    if git_p (ed):
        os.chdir (ed)
        if len (d) > 1:
            if d[-1] != "/":
                d = d + "/"
        print_git (cmd, d)
